/*
 ============================================================================
 Name        : BlockSearch.cpp
 Author      : 
 Version     :
 Copyright   : 
 Description : CBlockSearch implementation
 ============================================================================
 */

#include "BlockSearch.h"
#include "Field.h"
#include "Global.h"
#include "eStockappui.h"
#include "Goods.h"
#include "BlockQuote.h"
#include "BlockGrid.h"
#include <eStock_L2hy.rsg>
#include "BlockPicCur.h"

CBlockSearch::CBlockSearch(CBaseBlock* bsBack) :
	CBlock(bsBack), m_bSearchStation(-1)
{
	iHighlight = 0;
	iOffset = 0;
	iHeight = m_nLineHeight;
}

CBlockSearch::~CBlockSearch()
{
	m_pGN.Close();
	if (iFlickable != NULL)
		delete iFlickable, iFlickable = NULL;
	
	if(m_DelayTimer)
	{
		m_DelayTimer->Cancel();
		delete m_DelayTimer;
	}
}

CBlockSearch* CBlockSearch::NewLC(CBaseBlock* bsBack)
{
	CBlockSearch* self = new (ELeave) CBlockSearch(bsBack);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
}

CBlockSearch* CBlockSearch::NewL(CBaseBlock* bsBack)
{
	CBlockSearch* self = CBlockSearch::NewLC(bsBack);
	CleanupStack::Pop(); // self;
	return self;
}

void CBlockSearch::ConstructL()
{
	CBlock::ConstructL();
	CGlobal::GetDesFromID(m_strTitle, LOC_BUF_MENU_MATCHSHARES);

	CGlobal::GetDesFromID(m_bufMatching, LOC_BUF_STR_MATCHSTOCK);
	CGlobal::GetDesFromID(m_bufNoMatch, LOC_BUF_STR_SEARCHFAIL);

	m_sbVert->m_bScroll2End = ETrue;

	iFlickable = CFlickable::NewL();
	iFlickable->SetAcceptMouseClick(this);
	iFlickable->SetThreshold(m_nLineHeight);
}

TPoint CBlockSearch::ScrollOffset() const
{
	return TPoint(0, iOffset);
}

void CBlockSearch::SetScrollOffset(const TPoint& aOffset)
{
	TInt y = aOffset.iY;
	if (y != iOffset)
	{
		iOffset = Max(0, Min(iHeight * m_pGN.Count() - iListRect.Height(), y));
		DrawNow();

		if (m_bShowScroll)
		{
			TInt size = m_pGN.Count();
			if (iStartItem == 0)
				m_sbVert->SetPos(iStartItem);
			else if (iEndItem == size - 1)
				m_sbVert->SetPos(iEndItem);
			else
				m_sbVert->SetPos((iStartItem + iEndItem) / 2);
		}
	}
}

void CBlockSearch::SizeChanged()
{
	CBlock::SizeChanged();
	iToolbar->SetSoftKey(CToolbar::EOK, CToolbar::EBack);
	iListRect = m_rect;
}

void CBlockSearch::BeforeDraw(CFbsBitGc& g) const
{
	iTitlebar->SetTitleText(m_strTitle);
	CBlock::BeforeDraw(g);
}

void CBlockSearch::OnDraw(CFbsBitGc& g) const
{
	TInt nSize = m_pGN.Count();
	if (!m_bSocketed)
	{
		CGlobal::DrawString(g, m_bufMatching, 0, m_rect.iTl.iY, TOP | LEFT,
				m_pGlobal->g_rgbText);
		return;
	}
	else if (nSize == 0)
	{
		CGlobal::DrawString(g, m_bufNoMatch, 0, m_rect.iTl.iY, TOP | LEFT,
				m_pGlobal->g_rgbText);
		return;
	}

	if (nSize > 0)
	{
		TField field;
		field.m_sID = NAMECODE;

		iStartItem = iOffset / iHeight;
		TInt y = iListRect.iTl.iY + iStartItem * iHeight - iOffset;
		if (iOffset <= 0)
		{
			iStartItem = 0;
			y = iListRect.iTl.iY;
		}
		iEndItem = iStartItem + iListRect.Height() / iHeight + 1;
		if (iEndItem > nSize - 1)
			iEndItem = nSize - 1;

		g.SetClippingRect(iListRect);
		for (TInt i = iStartItem; i <= iEndItem; ++i, y += iHeight)
		{
			if (iHighlight == i)
				DrawImageRect(g, 0, y, m_rect.Width(), y + iHeight, 1);
			CGlobal::DrawString(g, m_pGN[i].m_strName, 0, y, TOP | LEFT,
					m_pGlobal->g_rgbText);
			field.m_lValue = m_pGN[i].m_nGoodsID;
			field.m_nGoodsID = m_pGN[i].m_nGoodsID;
			field.Draw(g, m_rect.iBr.iX, y, RIGHT);
		}
		g.CancelClippingRect();
	}
}

void CBlockSearch::OnKeyDown(TInt keyCode)
{
	if (keyCode == m_pGlobal->g_nKeyUp || keyCode == m_pGlobal->g_nKeyDown)
	{
		TInt nLine = m_pGN.Count();
		if (nLine > 1)
		{
			TInt nOldCurrent = iHighlight;
			if (keyCode == m_pGlobal->g_nKeyUp)
			{
				iHighlight--;
				if (iHighlight < 0)
					iHighlight = 0;
				else
				{
					if (iHighlight * iHeight < iOffset)
						iOffset -= iHeight;
				}
			}
			else if (keyCode == m_pGlobal->g_nKeyDown)
			{
				iHighlight++;
				if (iHighlight >= nLine)
					iHighlight = nLine - 1;
				else
				{
					if (iOffset + iListRect.Height() < (iHighlight + 1) * iHeight)
						iOffset += iHeight;
				}
			}
			else if (keyCode == m_pGlobal->g_nKeyLeft)
			{
				iHighlight -= m_nLinesPerPage;
				if (iHighlight < 0)
					iHighlight = 0;
			}
			else
			{
				iHighlight += m_nLinesPerPage;
				if (iHighlight >= nLine)
					iHighlight = nLine - 1;
			}

			if (nOldCurrent != iHighlight)
			{
				if (m_bShowScroll)
					m_sbVert->SetPos(iHighlight);
				DrawNow();
			}
		}
	}
	else if (keyCode == m_pGlobal->g_nKeySelect || keyCode
			== m_pGlobal->g_nKeyOK || keyCode == EStdKeyNkpAsterisk || keyCode
			== '*')
	{
		if (m_pGN.Count() > 0)
		    GoToGood(m_pGN[iHighlight].m_nGoodsID);
		else if (m_pGN.Count() == 0)
		{
			if(eStockUI->GetCurView() && eStockUI->GetCurView()->iContainer)
				eStockUI->GetCurView()->iContainer->DelBlock();
		}			
	}
	else if (keyCode == m_pGlobal->g_nKeyCancel)
	{
		if(eStockUI->GetCurView() && eStockUI->GetCurView()->iContainer)
	    	eStockUI->GetCurView()->iContainer->DelBlock();
	}
	else
		CBlock::OnKeyDown(keyCode);
}

void CBlockSearch::OnInput(const TDesC8& strInput)
{
	CBlock::OnInput(strInput);
}

TInt CBlockSearch::OnDelay(TAny* aAny)
{
	CBlockSearch* self = static_cast<CBlockSearch*>( aAny );
	self->m_DelayTimer->Cancel();
	
	
	if (self->m_pGN.Count() == 1)
	{
	    TInt goodsID = self->m_pGN[0].m_nGoodsID;
	    self->GoToGood(goodsID);
	}
	else if (self->m_pGN.Count() == 0)
	{
		if(eStockUI->GetCurView() && eStockUI->GetCurView()->iContainer)
		    eStockUI->GetCurView()->iContainer->DelBlock();
	}
	
	return KErrNone;
}

TBool CBlockSearch::ReadData(const TDesC8& aData)
{
	TPtrC8 ptr(aData);
	m_bSocketed = ETrue;
	m_bExit = ETrue;
	m_pGN.Reset();
	TInt16 nSize = CGlobal::ReadInt16L(ptr);

	for (TInt i = 0; i < nSize; i++)
	{
		TInt32 id = CGlobal::ReadInt32L(ptr);
		HBufC* pbuf = CGlobal::ReadStringL(ptr);
		TGoodsName goodname(id, pbuf->Des());
		delete pbuf;
		m_pGN.Append(goodname);
		m_pGlobal->UpdateGoods(goodname.m_nGoodsID, goodname.m_strName);
	}
	
	if (nSize == 0 || nSize == 1)
	{
		if(m_DelayTimer == NULL)
			m_DelayTimer = CPeriodic::NewL(CActive::EPriorityIdle);
		if(!m_DelayTimer->IsActive())
			m_DelayTimer->Start(1000000, 1000000, TCallBack(OnDelay, this));
	}

	SetScrollBar(iHighlight, nSize);
	return ETrue;
}

void CBlockSearch::WriteData(TDes8& aBuf)
{
	CGlobal::WriteInt8L(aBuf, m_bSearchStation);
	TInt32 nBlockSearch = m_pbSearchInput.Length();
	CGlobal::WriteInt8L(aBuf, nBlockSearch);
	aBuf.Append(m_pbSearchInput);
}

TInt CBlockSearch::GetDataLength()
{
	return m_pbSearchInput.Length() + 2;
}

TInt16 CBlockSearch::GetDataType()
{
	return RequestDataType_Search;
}

void CBlockSearch::ChangeScrollPos(TInt /*nPos*/)
{
	//	if (iHighlight!=nPos)
	//	{
	//		iHighlight = nPos;
	//		DrawNow();
	//	}
}

void CBlockSearch::OnMouseDown(const TPoint& aPt)
{
	iFlickable->HandleMousePress(aPt);
}

void CBlockSearch::OnMouseMove(const TPoint& aPt)
{
	iFlickable->HandleMouseMove(aPt);
}

void CBlockSearch::OnMouseUp(const TPoint& aPt)
{
	if (iFlickable->HandleMouseRelease(aPt))
		return;

	int y = aPt.iY - iListRect.iTl.iY + iOffset;
	int i = y / iHeight;
	if (i != iHighlight) 
	{
		iHighlight = i;
		DrawNow();
	}
	else if (i == iHighlight)
		OnKeyDown(m_pGlobal->g_nKeySelect);
}
